# 导入SQLAlchemy的create_engine、Column、Integer、String、ForeignKey等组件
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey

# 导入relationship用于定义表间关系，declarative_base用于创建ORM基类
from sqlalchemy.orm import relationship, declarative_base
from sqlalchemy.ext.hybrid import hybrid_property

# 创建MySQL数据库连接引擎，指定数据库连接字符串
engine = create_engine("mysql+pymysql://root:968716asD@localhost:3306/jobs")
# 创建声明性基类，所有ORM模型类都将继承自该基类
Base = declarative_base()


# 定义User模型类，继承自Base
class User(Base):
    # 指定该模型对应的表名为'users'
    __tablename__ = "users"

    # 定义id字段，类型为整型，主键
    id = Column(Integer, primary_key=True)
    # 定义name字段，类型为字符串
    name = Column(String)
    # 定义fullname字段，类型为字符串
    fullname = Column(String)
    # 定义与Address表的一对多关系，back_populates用于反向引用
    addresses = relationship("Address", back_populates="user")

    # 使用hybrid_property装饰器定义混合属性，该属性既可以在Python对象上使用，也可以在SQL查询中使用
    @hybrid_property
    # 定义description方法，用于生成用户的描述信息
    def description(self):
        # 使用列表推导式获取用户所有地址的邮箱地址，并用逗号连接成字符串
        email_addresses = ", ".join([addr.email_address for addr in self.addresses])
        # 返回包含用户全名和邮箱地址的描述字符串
        return f"{self.fullname} {email_addresses}"


# 定义Address模型类，继承自Base
class Address(Base):
    # 指定该模型对应的表名为'addresses'
    __tablename__ = "addresses"

    # 定义id字段，类型为整型，主键
    id = Column(Integer, primary_key=True)
    # 定义email_address字段，类型为字符串，不能为空
    email_address = Column(String, nullable=False)
    # 定义user_id字段，类型为整型，外键关联users表的id字段
    user_id = Column(Integer, ForeignKey("users.id"))
    # 定义与User表的多对一关系，back_populates用于反向引用
    user = relationship("User", back_populates="addresses")


# 在数据库中创建所有已定义的表
Base.metadata.create_all(engine)

# 导入sessionmaker用于创建数据库会话
from sqlalchemy.orm import sessionmaker

# 创建会话工厂，并绑定到数据库引擎
Session = sessionmaker(bind=engine)
# 创建数据库会话对象，用于与数据库进行交互
session = Session()
# 查询User表中的第一个用户对象
user = session.query(User).filter_by(id=1).first()
# 打印用户的描述信息（包含姓名和邮箱地址）
print(user.description)
